"""
作者: 临渊
日期: 2025/8/7
name: code版_飞蚂蚁
入口: 微信小程序 (https://a.c1ns.cn/iJAKu)
功能: 签到、步数兑换、奖池投注、获取用户豆子
变量: PROXY_API_URL (代理api，返回一条txt文本，内容为代理ip:端口)
    DEBUG_WXID (调试模式指定微信ID)
    yuanshen_api (过检软件API地址)
定时: 一天三次
# new Env("飞蚂蚁回收")
# cron: 10 6-8 * * *
------------更新日志------------
2025/8/7   V2.2    修复登录成功判断逻辑
"""

import random
import time
import requests
import os
import sys
import logging
import traceback
import ssl
import json
from datetime import datetime

MULTI_ACCOUNT_SPLIT = ["\n", "@"] # 分隔符列表
MULTI_ACCOUNT_PROXY = False # 是否使用多账号代理，默认不使用，True则使用多账号代理
NOTIFY = os.getenv("LY_NOTIFY") or False # 是否推送日志，默认不推送，True则推送
YUANSHEN_API = "http://" + os.getenv("yuanshen_api") if os.getenv("yuanshen_api") else None  # 过检软件API地址
TARGET_APP_ID = "wx501990400906c9ff"  # 目标小程序的APP_ID
DEBUG_WXID = os.getenv("DEBUG_WXID")  # 调试模式指定微信ID

# 请求头
REQUEST_HEADERS = {
    'Host': 'openapp.fmy90.com',
    'Connection': 'keep-alive',
    'Content-Length': '72',
    'Authorization': '',  # 使用Authorization头字段
    'charset': 'utf-8',
    'User-Agent': 'Mozilla/5.0 (Linux; Android 10; V1824A Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.103 Mobile Safari/537.36 XWEB/1300473 MMWEBSDK/20230805 MMWEBID/5374 MicroMessenger/8.0.42.2460(0x28002A35) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android',
    'content-type': 'application/json',
    'Referer': 'https://servicewechat.com/wx501990400906c9ff/225/page-frame.html',
    'Accept-Encoding': 'gzip,compress,br,deflate',
}

class TLSAdapter(requests.adapters.HTTPAdapter):
    """
    自定义TLS
    解决unsafe legacy renegotiation disabled
    """
    def init_poolmanager(self, *args, **kwargs):
        ctx = ssl.create_default_context()
        ctx.set_ciphers("DEFAULT@SECLEVEL=1")
        ctx.options |= 0x4   # <-- the key part here, OP_LEGACY_SERVER_CONNECT
        kwargs["ssl_context"] = ctx
        return super(TLSAdapter, self).init_poolmanager(*args, **kwargs)

class AutoTask:
    def __init__(self, script_name):
        """
        初始化自动任务类
        :param script_name: 脚本名称，用于日志显示
        """
        self.script_name = script_name
        self.wx_appid = TARGET_APP_ID # 微信小程序id
        self.proxy_url = os.getenv("PROXY_API_URL") # 代理api，返回一条txt文本，内容为代理ip:端口
        self.host = "openapp.fmy90.com"
        self.nickname = ""
        self.ck_file = "飞蚂蚁.json"  # CK存储文件名
        self.log_msgs = []  # 日志消息列表
        self.debug_mode = bool(DEBUG_WXID)  # 是否调试模式
        self.debug_wxid = DEBUG_WXID  # 调试指定的微信ID
        
    def log(self, msg, level="info"):
        """
        记录日志
        :param msg: 日志消息
        :param level: 日志级别
        """
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        log_msg = f"[{timestamp}] [{level.upper()}] {msg}"
        print(log_msg)
        self.log_msgs.append(log_msg)
        
        if level == "error":
            logging.error(log_msg)
        elif level == "warning":
            logging.warning(log_msg)
        else:
            logging.info(log_msg)

    def get_proxy(self):
        """
        获取代理
        :return: 代理
        """
        if not self.proxy_url:
            self.log("[获取代理] 没有找到环境变量PROXY_API_URL，不使用代理", level="warning")
            return None
        url = self.proxy_url
        response = requests.get(url)
        proxy = response.text
        self.log(f"[获取代理] {proxy}")
        return proxy

    def get_wx_list(self):
        """获取微信账户列表"""
        try:
            if not YUANSHEN_API:
                self.log("没有配置过检软件API地址(yuanshen_api)，无法获取微信账号列表", level="error")
                return []
                
            url = f"{YUANSHEN_API}/getallwx"
            response = requests.get(url, timeout=10)
            wx_list = response.json() if response.status_code == 200 else []
            
            # 调试模式：只保留指定的微信ID
            if self.debug_mode:
                wx_list = [acc for acc in wx_list if acc.get("Wxid") == self.debug_wxid]
                if wx_list:
                    self.log(f"调试模式：只处理微信ID {self.debug_wxid}", level="info")
                else:
                    self.log(f"调试模式：未找到微信ID {self.debug_wxid}", level="warning")
            
            return wx_list
        except Exception as e:
            self.log(f"获取微信列表失败: {str(e)}", level="error")
            return []

    def get_wx_code(self, wxid):
        """获取小程序登录凭证"""
        try:
            if not YUANSHEN_API:
                self.log("没有配置过检软件API地址(yuanshen_api)，无法获取微信code", level="error")
                return None
                
            url = f"{YUANSHEN_API}/loginbyapp?Wxid={wxid}&appid={self.wx_appid}"
            response = requests.get(url, timeout=10)
            if response.status_code == 200:
                return response.json().get("code")
            self.log(f"获取wxCode失败: HTTP {response.status_code}", level="error")
        except Exception as e:
            self.log(f"wxCode请求异常: {str(e)}", level="error")
        return None

    def get_ck(self, wx_code):
        """
        获取小程序登录凭证（CK）
        飞蚂蚁登录接口
        """
        login_url = f"https://{self.host}/auth/wx/login"
        # 修复登录参数格式问题
        payload = {
            "code": wx_code,
            "platformKey": "F2EE24892FBF66F0AFF8C0EB532A9394",
            "version": "V2.00.01",
            "vital": "",
            "partner_platform_key": ""
        }

        try:
            # 使用JSON格式发送请求
            response = requests.post(
                login_url, 
                headers={
                    "User-Agent": "Mozilla/5.0 (Linux; Android 12; M2012K11AC Build/SKQ1.220303.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/134.0.6998.136 Mobile Safari/537.36 XWEB/1340129 MMWEBSDK/20240301 MMWEBID/9871 MicroMessenger/8.0.48.2580(0x28003036) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android",
                    "Content-Type": "application/json"
                },
                json=payload,  # 使用json参数发送JSON数据
                timeout=15
            )
            self.log(f"登录响应: {response.text}")
            
            if response.status_code == 200:
                try:
                    res_data = response.json()
                    # 修复：飞蚂蚁接口成功时返回code:200
                    if res_data.get('code') == 200:
                        token = res_data.get('data', {}).get('token', '')
                        if token:
                            # 提取用户信息
                            user_data = res_data.get('data', {}).get('user', {})
                            user_name = user_data.get('userName', '未知用户')
                            
                            self.log(f"✅ 登录成功, 获取到token")
                            
                            # 返回CK
                            return {
                                "ck": token,
                                "nickname": user_name  # 使用飞蚂蚁返回的用户名
                            }
                        else:
                            self.log("❌ 响应中未找到token字段", level="warning")
                    else:
                        error_msg = res_data.get('msg', '未知错误')
                        self.log(f"❌ 登录失败: {error_msg}", level="error")
                except json.JSONDecodeError:
                    self.log(f"❌ 响应不是有效的JSON: {response.text}", level="error")
            else:
                self.log(f"❌ 请求失败: HTTP {response.status_code}, {response.text}", level="error")
        except Exception as e:
            self.log(f"❌ 登录异常: {e}", level="error")
        
        return None

    def validate_ck(self, ck):
        """验证 Bearer Token 的有效性"""
        url = f"https://{self.host}/user/new/beans/info"  
        headers = {
            'Host': self.host,
            'Connection': 'keep-alive',
            'Authorization': f"bearer {ck}",
            'charset': 'utf-8',
            'User-Agent': 'Mozilla/5.0 (Linux; Android 12; M2012K11AC Build/SKQ1.220303.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/134.0.6998.136 Mobile Safari/537.36 XWEB/1340129 MMWEBSDK/20240301 MMWEBID/9871 MicroMessenger/8.0.48.2580(0x28003036) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android',
            'content-type': 'application/json',
            'Referer': f'https://servicewechat.com/{self.wx_appid}/225/page-frame.html',
            'Accept-Encoding': 'gzip,compress,br,deflate',
        }
        params = {
            "type": 1,
            "version": "V2.00.01",
            "platformKey": "F2EE24892FBF66F0AFF8C0EB532A9394",
            "mini_scene": 1008,
            "partner_ext_infos": ""
        }

        try:
            response = requests.get(url, headers=headers, params=params, timeout=10)
            if response.status_code == 200:
                try:
                    data = response.json()
                    if data.get("code") == 200:  # 修复：飞蚂蚁接口成功时返回code:200
                        self.log(f"✅ CK验证成功")
                        return True
                    else:
                        self.log(f"❌ CK验证失败: {data.get('msg', '未知错误')}", level="warning")
                except json.JSONDecodeError:
                    self.log(f"❌ CK验证响应不是JSON: {response.text[:200]}", level="warning")
            else:
                self.log(f"❌ CK验证失败: HTTP {response.status_code}", level="warning")
        except Exception as e:
            self.log(f"❌ CK验证请求出错: {e}", level="error")
        return False

    def load_ck_from_file(self):
        """从文件加载CK并验证有效性"""
        valid_results = []
        expired_accounts = []
        
        if not os.path.exists(self.ck_file):
            return valid_results, expired_accounts, set()
        
        try:
            with open(self.ck_file, "r") as f:
                ck_results = json.load(f)
                # 验证CK有效性
                for acc in ck_results:
                    # 调试模式：只处理指定微信ID
                    if self.debug_mode and acc.get("wxid") != self.debug_wxid:
                        continue
                        
                    if self.validate_ck(acc["ck"]):
                        valid_results.append(acc)
                    else:
                        self.log(f"❌ CK已失效: {acc.get('wxname', '未知账户')}", level="warning")
                        expired_accounts.append(acc)
        
            if valid_results:
                self.log(f"✅ 从文件加载 {len(valid_results)} 个有效CK")
            if expired_accounts:
                self.log(f"⚠️ 检测到 {len(expired_accounts)} 个失效CK", level="warning")
                
            # 返回现有wxid集合用于检测新账号
            existing_wxids = {acc["wxid"] for acc in ck_results}
            return valid_results, expired_accounts, existing_wxids
        except Exception as e:
            self.log(f"加载CK文件失败: {str(e)}", level="error")
            return [], [], set()

    def save_ck_to_file(self, ck_results):
        """保存CK到文件"""
        try:
            # 如果文件已存在，合并新旧数据
            existing_data = []
            if os.path.exists(self.ck_file):
                with open(self.ck_file, "r") as f:
                    existing_data = json.load(f)
            
            # 创建wxid到账号的映射
            account_map = {acc["wxid"]: acc for acc in existing_data}
            
            # 更新或添加新CK
            for new_acc in ck_results:
                account_map[new_acc["wxid"]] = new_acc
            
            merged_results = list(account_map.values())
            
            with open(self.ck_file, "w") as f:
                json.dump(merged_results, f, indent=2)
            self.log(f"💾 成功保存 {len(merged_results)} 个CK到 {self.ck_file}")
        except Exception as e:
            self.log(f"保存CK文件失败: {str(e)}", level="error")

    def fetch_ck(self, wx_accounts):
        """
        获取指定微信账号的CK
        :param wx_accounts: 需要获取CK的微信账号列表
        :return: 新获取的CK列表
        """
        if not wx_accounts:
            self.log("❌ 未提供微信账户列表", level="error")
            return []
        
        self.log(f"✅ 准备获取 {len(wx_accounts)} 个微信账户的CK")
        
        ck_results = []
        for account in wx_accounts:
            wxid = account.get("Wxid")
            wxname = account.get("wxname", "未知账户")  # 微信昵称
            
            # 调试模式：只处理指定微信ID
            if self.debug_mode and wxid != self.debug_wxid:
                continue
                
            # 使用微信昵称而不是微信ID
            self.log(f"\n🔍 处理账户: {wxname}")
            
            wx_code = self.get_wx_code(wxid)
            if not wx_code:
                self.log("❌ 获取wxCode失败")
                continue
            
            self.log(f"🔑 获取到wxCode: {wx_code[:8]}****")
            
            auth_data = self.get_ck(wx_code)
            if auth_data:
                ck = auth_data["ck"]
                nickname = auth_data["nickname"]  # 使用飞蚂蚁返回的用户名
                
                self.log(f"🔐 获取CK成功: {ck[:23]}****")
                self.log(f"👤 用户昵称: {nickname}")
                
                ck_results.append({
                    "wxid": wxid,
                    "wxname": nickname,  # 使用飞蚂蚁返回的用户名
                    "ck": ck
                })
            else:
                self.log("❌ 获取CK失败")
    
        if not ck_results:
            self.log("\n❌ 未获取到有效CK", level="warning")
            return []
        
        return ck_results

    def merge_ck_lists(self, original_list, new_list):
        """
        合并新旧CK列表
        :param original_list: 原始有效CK列表
        :param new_list: 新获取的CK列表
        :return: 合并后的CK列表
        """
        # 创建wxid到账号的映射
        account_map = {acc["wxid"]: acc for acc in original_list}
        
        # 更新或添加新CK
        for new_acc in new_list:
            account_map[new_acc["wxid"]] = new_acc
        
        return list(account_map.values())

    def detect_new_accounts(self, current_wx_list, existing_wxids):
        """
        检测新的微信账号
        :param current_wx_list: 当前微信账号列表
        :param existing_wxids: 已有CK中的wxid集合
        :return: 新账号列表
        """
        new_accounts = []
        for account in current_wx_list:
            wxid = account.get("Wxid")
            if wxid not in existing_wxids:
                new_accounts.append(account)
        
        return new_accounts

    # ======== 飞蚂蚁任务函数 ========
    def sign_in(self, session, ck):
        """
        执行签到
        :param session: session
        :param ck: 认证token
        """
        try:
            url = f"https://{self.host}/sign/new/do"
            headers = {
                "Host": self.host,
                "Connection": "keep-alive",
                "Authorization": f"bearer {ck}",
                "charset": "utf-8",
                "User-Agent": "Mozilla/5.0 (Linux; Android 12; M2012K11AC Build/SKQ1.220303.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/134.0.6998.136 Mobile Safari/537.36 XWEB/1340129 MMWEBSDK/20240301 MMWEBID/9871 MicroMessenger/8.0.48.2580(0x28003036) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android",
                "content-type": "application/json",
                "Referer": f"https://servicewechat.com/{self.wx_appid}/225/page-frame.html",
                "Accept-Encoding": "gzip,compress,br,deflate",
            }
            payload = {
                "version": "V2.00.01",
                "platformKey": "F2EE24892FBF66F0AFF8C0EB532A9394",
                "mini_scene": 1008,
                "partner_ext_infos": ""
            }
            response = session.post(url, headers=headers, json=payload)
            response.raise_for_status()
            response_json = response.json()
            # 修复：飞蚂蚁接口成功时返回code:200
            if response_json.get('code') == 200:
                self.log(f"[{self.nickname}] 签到成功: {response_json.get('message', '未知结果')}")
                return True
            else:
                self.log(f"[{self.nickname}] 签到失败: {response_json.get('message', '未知结果')}", level="warning")
                return False
        except requests.RequestException as e:
            self.log(f"[{self.nickname}] 签到发生网络错误: {str(e)}", level="error")
            return False
        except Exception as e:
            self.log(f"[{self.nickname}] 签到发生未知错误: {str(e)}\n{traceback.format_exc()}", level="error")
            return False

    def step_exchange(self, session, ck):
        """
        执行步数兑换
        :param session: session
        :param ck: 认证token
        """
        try:
            url = f"https://{self.host}/step/exchange"
            headers = {
                "Host": self.host,
                "Connection": "keep-alive",
                "Authorization": f"bearer {ck}",
                "charset": "utf-8",
                "User-Agent": "Mozilla/5.0 (Linux; Android 12; M2012K11AC Build/SKQ1.220303.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/134.0.6998.136 Mobile Safari/537.36 XWEB/1340129 MMWEBSDK/20240301 MMWEBID/9871 MicroMessenger/8.0.48.2580(0x28003036) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android",
                "content-type": "application/json",
                "Referer": f"https://servicewechat.com/{self.wx_appid}/225/page-frame.html",
                "Accept-Encoding": "gzip,compress,br,deflate",
            }
            payload = {
                "steps": 10000,
                "version": "V2.00.01",
                "platformKey": "F2EE24892FBF66F0AFF8C0EB532A9394",
                "mini_scene": 1008,
                "partner_ext_infos": ""
            }
            response = session.post(url, headers=headers, json=payload)
            response.raise_for_status()
            response_json = response.json()
            # 修复：飞蚂蚁接口成功时返回code:200
            if response_json.get('code') == 200:
                self.log(f"[{self.nickname}] 步数兑换成功: {response_json.get('message', '未知结果')}")
                return True
            else:
                self.log(f"[{self.nickname}] 步数兑换失败: {response_json.get('message', '未知结果')}", level="warning")
                return False
        except requests.RequestException as e:
            self.log(f"[{self.nickname}] 步数兑换发生网络错误: {str(e)}", level="error")
            return False
        except Exception as e:
            self.log(f"[{self.nickname}] 步数兑换发生未知错误: {str(e)}\n{traceback.format_exc()}", level="error")
            return False
        
    def pool_bet(self, session, ck):
        """
        执行奖池投注
        :param session: session
        :param ck: 认证token
        """
        try:
            url = f"https://{self.host}/active/pool/bet"
            headers = {
                "Host": self.host,
                "Connection": "keep-alive",
                "Authorization": f"bearer {ck}",
                "charset": "utf-8",
                "User-Agent": "Mozilla/5.0 (Linux; Android 12; M2012K11AC Build/SKQ1.220303.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/134.0.6998.136 Mobile Safari/537.36 XWEB/1340129 MMWEBSDK/20240301 MMWEBID/9871 MicroMessenger/8.0.48.2580(0x28003036) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android",
                "content-type": "application/json",
                "Referer": f"https://servicewechat.com/{self.wx_appid}/225/page-frame.html",
                "Accept-Encoding": "gzip,compress,br,deflate",
            }
            payload = {
                "version": "V2.00.01",
                "platformKey": "F2EE24892FBF66F0AFF8C0EB532A9394",
                "mini_scene": 1008,
                "partner_ext_infos": ""
            }
            response = session.post(url, headers=headers, json=payload)
            response.raise_for_status()
            response_json = response.json()
            # 修复：飞蚂蚁接口成功时返回code:200
            if response_json.get('code') == 200:
                self.log(f"[{self.nickname}] 奖池投注成功: {response_json.get('message', '未知结果')}")
                return True
            else:
                self.log(f"[{self.nickname}] 奖池投注失败: {response_json.get('message', '未知结果')}", level="warning")
                return False
        except requests.RequestException as e:
            self.log(f"[{self.nickname}] 奖池投注发生网络错误: {str(e)}", level="error")
            return False
        except Exception as e:
            self.log(f"[{self.nickname}] 奖池投注发生未知错误: {str(e)}\n{traceback.format_exc()}", level="error")
            return False

    def pool_sign(self, session, ck):
        """
        执行奖池签到
        :param session: session
        :param ck: 认证token
        """
        try:
            url = f"https://{self.host}/active/pool/sign"
            headers = {
                "Host": self.host,
                "Connection": "keep-alive",
                "Authorization": f"bearer {ck}",
                "charset": "utf-8",
                "User-Agent": "Mozilla/5.0 (Linux; Android 12; M2012K11AC Build/SKQ1.220303.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/134.0.6998.136 Mobile Safari/537.36 XWEB/1340129 MMWEBSDK/20240301 MMWEBID/9871 MicroMessenger/8.0.48.2580(0x28003036) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android",
                "content-type": "application/json",
                "Referer": f"https://servicewechat.com/{self.wx_appid}/225/page-frame.html",
                "Accept-Encoding": "gzip,compress,br,deflate",
            }
            payload = {
                "version": "V2.00.01",
                "platformKey": "F2EE24892FBF66F0AFF8C0EB532A9394",
                "mini_scene": 1008,
                "partner_ext_infos": ""
            }
            response = session.post(url, headers=headers, json=payload)
            response.raise_for_status()
            response_json = response.json()
            # 修复：飞蚂蚁接口成功时返回code:200
            if response_json.get('code') == 200:
                self.log(f"[{self.nickname}] 奖池签到成功: {response_json.get('message', '未知结果')}")
                return True
            else:
                self.log(f"[{self.nickname}] 奖池签到失败: {response_json.get('message', '未知结果')}", level="warning")
                return False
        except requests.RequestException as e:
            self.log(f"[{self.nickname}] 奖池签到发生网络错误: {str(e)}", level="error")
            return False
        except Exception as e:
            self.log(f"[{self.nickname}] 奖池签到发生未知错误: {str(e)}\n{traceback.format_exc()}", level="error")
            return False

    def get_user_beans(self, session, ck):
        """
        获取用户豆子
        :param session: session
        :param ck: 认证token
        """
        try:
            url = f"https://{self.host}/user/new/beans/info"
            headers = {
                "Host": self.host,
                "Connection": "keep-alive",
                "Authorization": f"bearer {ck}",
                "charset": "utf-8",
                "User-Agent": "Mozilla/5.0 (Linux; Android 12; M2012K11AC Build/SKQ1.220303.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/134.0.6998.136 Mobile Safari/537.36 XWEB/1340129 MMWEBSDK/20240301 MMWEBID/9871 MicroMessenger/8.0.48.2580(0x28003036) WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android",
                "content-type": "application/json",
                "Referer": f"https://servicewechat.com/{self.wx_appid}/225/page-frame.html",
                "Accept-Encoding": "gzip,compress,br,deflate",
            }
            param = {
                "type": 1,
                "version": "V2.00.01",
                "platformKey": "F2EE24892FBF66F0AFF8C0EB532A9394",
                "mini_scene": 1008,
                "partner_ext_infos": ""
            }
            # 已获取豆子
            total_get_response = session.get(url, headers=headers, params=param)
            total_get_response_json = total_get_response.json()
            total_get_beans = total_get_response_json.get('data', {}).get('totalCount', 0)
            
            param['type'] = 2
            # 已使用豆子
            total_use_response = session.get(url, headers=headers, params=param)
            total_use_response_json = total_use_response.json()
            total_use_beans = total_use_response_json.get('data', {}).get('totalCount', 0)
            
            # 豆子余额
            total_beans = total_get_beans - total_use_beans
            self.log(f"[{self.nickname}] 豆子余额: {total_beans}")
            return total_beans
        except requests.RequestException as e:
            self.log(f"[{self.nickname}] 获取豆子余额发生网络错误: {str(e)}", level="error")
            return 0
        except Exception as e:
            self.log(f"[{self.nickname}] 获取豆子余额发生未知错误: {str(e)}\n{traceback.format_exc()}", level="error")
            return 0

    def run(self):
        """
        运行任务
        """
        try:
            self.log(f"【{self.script_name}】开始执行任务")
            if self.debug_mode:
                self.log(f"调试模式已启用，只处理微信ID: {self.debug_wxid}")
            
            # 第一步：尝试加载已有的CK并验证有效性
            valid_ck_list, expired_accounts, existing_wxids = self.load_ck_from_file()
            
            # 第二步：获取当前微信账户列表
            self.log("🔄 正在获取当前微信账户列表...")
            current_wx_list = self.get_wx_list()
            
            if not current_wx_list:
                self.log("❌ 未获取到任何微信账户，任务终止", level="error")
                return
                
            self.log(f"✅ 获取到 {len(current_wx_list)} 个微信账户")
            
            # 添加账号间初始延迟 (3-5秒)
            time.sleep(random.uniform(3, 5))
            
            # 第三步：检测新账号
            new_accounts = self.detect_new_accounts(current_wx_list, existing_wxids)
            if new_accounts:
                self.log(f"🎉 检测到 {len(new_accounts)} 个新账号:")
                for acc in new_accounts:
                    # 使用微信昵称而不是微信ID
                    self.log(f"  - {acc.get('wxname', '未知账号')}")
                
                # 获取新账号的CK
                new_ck_list = self.fetch_ck(new_accounts)
                if new_ck_list:
                    # 合并新账号到有效列表
                    merged_ck_list = self.merge_ck_lists(valid_ck_list, new_ck_list)
                    valid_ck_list = merged_ck_list
                    self.log(f"✅ 成功添加 {len(new_ck_list)} 个新账号的CK")
                else:
                    self.log("❌ 未能获取新账号的CK", level="warning")
            
            # 第四步：更新失效账号
            if expired_accounts:
                self.log("⚠️ 检测到失效CK，开始更新...", level="warning")
                # 构建需要更新的账号列表（仅限当前存在的账号）
                update_accounts = []
                for expired in expired_accounts:
                    # 查找当前微信列表中是否存在此wxid
                    for wx_acc in current_wx_list:
                        if wx_acc.get("Wxid") == expired["wxid"]:
                            update_accounts.append(wx_acc)
                            break
                
                if update_accounts:
                    updated_ck_list = self.fetch_ck(update_accounts)
                    if updated_ck_list:
                        # 合并更新后的CK
                        merged_ck_list = self.merge_ck_lists(valid_ck_list, updated_ck_list)
                        valid_ck_list = merged_ck_list
                        self.log(f"🔄 成功更新 {len(updated_ck_list)} 个失效账号的CK")
                    else:
                        self.log("❌ 未能更新失效账号的CK", level="error")
                else:
                    self.log("⚠️ 失效账号已不在当前微信列表中，跳过更新", level="warning")
            
            # 第五步：保存所有CK到文件
            if valid_ck_list:
                self.save_ck_to_file(valid_ck_list)
            else:
                # 如果没有有效CK，尝试获取所有账号的CK
                self.log("❌ 没有有效的CK，尝试获取所有账号的CK...", level="warning")
                all_ck_list = self.fetch_ck(current_wx_list)
                if all_ck_list:
                    self.save_ck_to_file(all_ck_list)
                    valid_ck_list = all_ck_list
                else:
                    self.log("❌ 未能获取任何CK，任务终止", level="error")
                    return
            
            # 第六步：执行任务
            if valid_ck_list:
                self.log(f"✅ 开始执行任务，共 {len(valid_ck_list)} 个账号")
                session = requests.Session()
                
                for account in valid_ck_list:
                    try:
                        wxid = account["wxid"]
                        wxname = account["wxname"]  # 获取飞蚂蚁用户名
                        ck = account["ck"]
                        
                        # 使用飞蚂蚁用户名
                        self.log(f"\n------ 开始处理账号: {wxname} ------")
                        self.nickname = wxname  # 设置当前昵称为飞蚂蚁用户名
                        
                        # 添加账号处理前延迟 (3-5秒)
                        time.sleep(random.uniform(3, 5))
                        
                        # 执行飞蚂蚁任务
                        # 1. 签到
                        self.sign_in(session, ck)
                        time.sleep(random.randint(3, 5))
                        
                        # 2. 步数兑换（直到提示每天最多兑换）
                        # 限制最多尝试5次，避免无限循环
                        max_attempts = 5
                        attempt = 0
                        while attempt < max_attempts and self.step_exchange(session, ck):
                            time.sleep(random.randint(3, 5))
                            attempt += 1
                        
                        # 3. 奖池投注
                        self.pool_bet(session, ck)
                        time.sleep(random.randint(3, 5))
                        
                        # 4. 奖池签到
                        self.pool_sign(session, ck)
                        time.sleep(random.randint(3, 5))
                        
                        # 5. 获取用户豆子
                        self.get_user_beans(session, ck)
                        
                        self.log(f"------ 账号处理完成 ------")
                        
                        # 账号间间隔 (5-8秒)
                        time.sleep(random.uniform(5, 8))
                        
                    except Exception as e:
                        self.log(f"处理账号 {wxname} 时出错: {str(e)}\n{traceback.format_exc()}", level="error")
                        continue
            else:
                self.log("❌ 没有有效的CK可用，任务终止", level="error")
                
        except Exception as e:
            self.log(f"【{self.script_name}】执行过程中发生错误: {str(e)}\n{traceback.format_exc()}", level="error")
        finally:
            if NOTIFY:
                # 如果notify模块不存在，从远程下载至本地
                if not os.path.exists("notify.py"):
                    url = "https://raw.githubusercontent.com/whyour/qinglong/refs/heads/develop/sample/notify.py"
                    response = requests.get(url)
                    with open("notify.py", "w", encoding="utf-8") as f:
                        f.write(response.text)
                    import notify
                else:
                    import notify
                # 任务结束后推送日志
                title = f"{self.script_name} 运行日志"
                header = "作者：临渊\n"
                content = header + "\n" +"\n".join(self.log_msgs)
                notify.send(title, content)


if __name__ == "__main__":
    auto_task = AutoTask("飞蚂蚁")
    auto_task.run()